package com.zx.framework.core.util;

import java.lang.annotation.Annotation;
import java.util.Locale;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.util.Assert;

/**
 * 用于获取spring声明的bean
 * @author stylewolf
 *
 */
public class SpringBeanUtil implements ApplicationContextAware {

	private static ApplicationContext context;//声明一个静态变量保存
	
	private static DefaultListableBeanFactory beanFactory;
	
	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException 
	{
		context = arg0;
		if (!DefaultListableBeanFactory.class.isAssignableFrom(context.getAutowireCapableBeanFactory().getClass())) {
            throw new IllegalArgumentException("BeanFactory must be DefaultListableBeanFactory type");
        }
		beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
	}
	/**
	 * 获取所有定义的bean名称
	 * @return
	 */
	public static String[]  getBeanList(){
		return context.getBeanDefinitionNames();
	}
	/**
	 * 获取指定类型的bean
	 * @param name
	 * @param clazz
	 * @return
	 */
	public static <T> T getBean(String name,Class<T> clazz)
	{
		try {
			return context.getBean(name,clazz);
		} catch (Exception e) {
			// 
			e.printStackTrace();
			return null;
		}
	}
	public static Object getBean(String name)
	{
		try {
			return context.getBean(name);
		} catch (BeansException e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 根据配置文件获取指定类型的bean
	 * @param beanName
	 * @return
	 */
	public static Object getBeanOfFile(String beanName,String p_szContextFile){
		ApplicationContext v_aContext = new ClassPathXmlApplicationContext(p_szContextFile);
		return v_aContext.getBean(beanName);
	}

    /**
     * 获取指定类型的beans
     * @param type class
     * @param <T> 泛型
     * @return 指定类型的bean组成的map
     */
    public static <T> Map<String,T> getBeanOfType(Class<T> type){
        return context.getBeansOfType(type);
    }

    /**
     * 获取包含指定注解的beans,bean必须受spring管理
     * @param annotationType 注解类型
     * @return 指定类型的bean组成的map
     */
    public static Map<String,Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType){
        return context.getBeansWithAnnotation(annotationType);
    }
	/**
	 * 获取国际化文件
	 * @param key
	 * @param args
	 * @return
	 */
	public static String getMessage(String key,String ... args ){
		return context.getMessage(key, args,"", Locale.getDefault());
	}
	/**
	 * 动态注册一个bean
	 * @param beanName bean的名称
	 * @param beanClass 
	 * @param mutablePropertyValues bean的属性设置
	 * @param initMethodName 初始化方法名称
	 * @param destroyMethodName 销毁时方法名称
	 */
	public void registerBean(String beanName, Class<?> beanClass,MutablePropertyValues mutablePropertyValues, String initMethodName, String destroyMethodName) {
        Assert.notNull(beanClass, "register bean class must not null");
        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClass(beanClass);
        if(mutablePropertyValues != null){
        	bd.setPropertyValues(mutablePropertyValues);
        }
        if(StringUtil.isNotEmpty(initMethodName) ){
        	bd.setInitMethodName(initMethodName);
        }
        if(StringUtil.isNotEmpty(destroyMethodName) ){
        	 bd.setDestroyMethodName(destroyMethodName);
        }
        
       
        if (StringUtil.isNotEmpty(beanName)) {
            beanFactory.registerBeanDefinition(beanName, bd);
        } else {
            BeanDefinitionReaderUtils.registerWithGeneratedName(bd, beanFactory);
        }

    }
	
	/**
	 * 动态注册一个bean
	 * @param beanName
	 * @param beanClass
	 * @param mutablePropertyValues bean的属性设置
	 * @see #registerBean(String beanName, Class<?> beanClass,MutablePropertyValues mutablePropertyValues, String initMethodName, String destroyMethodName) 
	 */
	public void registerBean(String beanName, Class<?> beanClass,MutablePropertyValues mutablePropertyValues) {
        registerBean(beanName, beanClass, mutablePropertyValues,null,null);

    }
	
	/**
	 * 动态注册一个bean
	 * @param beanName
	 * @param beanClass
	 * @see #registerBean(String beanName, Class<?> beanClass,MutablePropertyValues mutablePropertyValues, String initMethodName, String destroyMethodName) 
	 */
	public void registerBean(String beanName, Class<?> beanClass) {
        registerBean(beanName, beanClass, null,null,null);

    }
	
	/**
	 * 动态注册一个bean
	 * @param beanName
	 * @param beanClass
	 * @param initMethodName
	 * @see #registerBean(String beanName, Class<?> beanClass,MutablePropertyValues mutablePropertyValues, String initMethodName, String destroyMethodName) 
	 */
	public void registerBean(String beanName, Class<?> beanClass, String initMethodName) {
        registerBean(beanName, beanClass, null,initMethodName,null);
    }
	/**
	 * 动态解析xml配置
	 */
	public static void registerByXml(String path){
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory); 
		reader.loadBeanDefinitions(new FileSystemResource(path)); 
	}
}
